package core;

import java.util.HashMap;
import java.util.Random;
import java.util.Vector;

/**
 * @author Gary
 */
public abstract class GameEntity {

    // Entity Information
    protected int atk_min;
    protected int atk_max;
    protected float atk_delay;
    protected float atk_range;
    protected short defense;
    protected short gender;
    protected float heading;
    protected int health;
    protected int health_max;
    protected short level;
    protected String map_id;
    protected short model_id;
    protected float move_speed;
    protected String name;
    protected int object_id;
    protected float[] position;
    protected float scale;
    protected boolean status;
    // Base Values
    protected int base_atk_min;
    protected int base_atk_max;
    protected float base_atk_delay;
    protected float base_atk_range;
    protected short base_defense;
    protected int base_health;
    protected float base_move_speed;
    protected float base_scale;
    // Other Information
    protected HashMap<Short, Float> effectsList;
    protected Vector<Integer> targetList;
    // Extra Information
    protected int user_id;
    //man-protected GameTimer healthRegenTimer;

    public GameEntity() {
        position = new float[3];
        effectsList = new HashMap<Short, Float>();
        targetList = new Vector<Integer>();

        //man- healthRegenTimer = new GameTimer();
    }

    public GameEntity(int object_id, GameEntity entity) {
        this.object_id = object_id;

        atk_min = entity.getAttackMin();
        atk_max = entity.getAttackMax();
        atk_delay = entity.getAttackDelay();
        atk_range = entity.getAttackRange();
        defense = entity.getDefense();
        gender = entity.getGender();
        heading = entity.getH();
        health = entity.getHealth();
        health_max = entity.getHealthMax();
        level = entity.getLevel();
        map_id = entity.getMapID();
        model_id = entity.getModelID();
        move_speed = entity.getMoveSpeed();
        name = entity.getName();

        position = new float[3];
        System.arraycopy(entity.getPos(), 0, position, 0, 3);

        scale = entity.getScale();
        status = entity.getStatus();

        base_atk_min = entity.getBaseAttackMin();
        base_atk_max = entity.getBaseAttackMax();
        base_atk_delay = entity.getBaseAttackDelay();
        base_atk_range = entity.getBaseAttackRange();
        base_defense = entity.getBaseDefense();
        base_health = entity.getBaseHealth();
        base_move_speed = entity.getBaseMoveSpeed();
        base_scale = entity.getBaseScale();

        effectsList = new HashMap<Short, Float>();
        targetList = new Vector<Integer>();

        //man- healthRegenTimer = new GameTimer();
    }

    public int getAttackMin() {
        return atk_min;
    }

    public int setAttackMin(int atk_min) {
        if (atk_min <= 0) {
            atk_min = 1;
        } else if (atk_min > atk_max) {
            atk_min = atk_max;
        }

        return this.atk_min = atk_min;
    }

    public int getAttackMax() {
        return atk_max;
    }

    public int setAttackMax(int atk_max) {
        if (atk_max < 0) {
            atk_max = 1;
        }

        if (atk_min > atk_max) {
            atk_min = atk_max;
        }

        return this.atk_max = atk_max;
    }

    public int getAttackPower() {
        return new Random().nextInt(atk_max - atk_min + 1) + atk_min;
    }

    public void setAttackPower(int atk_min, int atk_max) {
        setAttackMax(atk_max);
        setAttackMin(atk_min);
    }

    public float getAttackDelay() {
        return atk_delay;
    }

    public float setAttackDelay(float atk_delay) {
        return this.atk_delay = atk_delay;
    }

    public float getAttackRange() {
        return atk_range;
    }

    public float setAttackRange(float atk_range) {
        return this.atk_range = atk_range;
    }

    public short getDefense() {
        return defense;
    }

    public short setDefense(short defense) {
        return this.defense = defense;
    }

    public short getGender() {
        return gender;
    }

    public short setGender(short gender) {
        return this.gender = gender;
    }

    public float getH() {
        return heading;
    }

    public float setH(float heading) {
        return this.heading = heading;
    }

    public int getHealth() {
        return health;
    }

    public int setHealth(int health) {
        if (health < 0) {
            health = 0;
        } else if (health > health_max) {
            health = health_max;
        }

        return this.health = health;
    }

    public int getHealthMax() {
        return health_max;
    }

    public int setHealthMax(int health_max) {
        if (health_max < 0) {
            health_max = 0;
        }

        if (health > health_max) {
            health = health_max;
        }

        return this.health_max = health_max;
    }

    public void setHealth(int health, int health_max) {
        setHealthMax(health_max);
        setHealth(health);
    }

    public int getID() {
        return object_id;
    }

    public int setID(int object_id) {
        return this.object_id = object_id;
    }

    public short getLevel() {
        return level;
    }

    public short setLevel(short level) {
        return this.level = level;
    }

    public String getMapID() {
        return map_id;
    }

    public String setMapID(String map_id) {
        return this.map_id = map_id;
    }

    public short getModelID() {
        return model_id;
    }

    public short setModelID(short model_id) {
        return this.model_id = model_id;
    }

    public float getMoveSpeed() {
        return move_speed;
    }

    public float setMoveSpeed(float move_speed) {
        return this.move_speed = move_speed;
    }

    public String getName() {
        return name;
    }

    public String setName(String name) {
        return this.name = name;
    }

    public float[] getPos() {
        return position;
    }

    public float[] setPos(float[] position) {
        return this.position = position;
    }

    public float[] setPos(float x, float y, float z) {
        position[0] = x;
        position[1] = y;
        position[2] = z;

        return position;
    }

    public float setScale(float scale) {
        return this.scale = scale;
    }

    public float getScale() {
        return scale;
    }

    public boolean getStatus() {
        return status;
    }

    public boolean setStatus(boolean status) {
        return this.status = status;
    }

    public float getX() {
        return position[0];
    }

    public float setX(float x) {
        return position[0] = x;
    }

    public float getY() {
        return position[1];
    }

    public float setY(float y) {
        return position[1] = y;
    }

    public float getZ() {
        return position[2];
    }

    public float setZ(float z) {
        return position[2] = z;
    }

    public float getBaseAttackDelay() {
        return base_atk_delay;
    }

    public float setBaseAttackDelay(float base_atk_delay) {
        return this.base_atk_delay = setAttackDelay(base_atk_delay);
    }

    public int getBaseAttackMin() {
        return base_atk_min;
    }

    public int setBaseAttackMin(int base_atk_min) {
        return this.base_atk_min = setAttackMin(base_atk_min);
    }

    public int getBaseAttackMax() {
        return base_atk_max;
    }

    public int setBaseAttackMax(int base_atk_max) {
        return this.base_atk_max = setAttackMax(base_atk_max);
    }

    public void setBaseAttackPower(int base_atk_min, int base_atk_max) {
        setBaseAttackMax(base_atk_max);
        setBaseAttackMin(base_atk_min);
    }

    public float getBaseAttackRange() {
        return base_atk_range;
    }

    public float setBaseAttackRange(float base_atk_range) {
        return this.base_atk_range = setAttackRange(base_atk_range);
    }

    public short getBaseDefense() {
        return base_defense;
    }

    public short setBaseDefense(short base_defense) {
        return this.base_defense = setDefense(base_defense);
    }

    public int getBaseHealth() {
        return base_health;
    }

    public int setBaseHealth(int base_health) {
        setHealth(base_health, base_health);
        return this.base_health = base_health;
    }

    public float getBaseMoveSpeed() {
        return base_move_speed;
    }

    public float setBaseMoveSpeed(float base_move_speed) {
        return this.base_move_speed = setMoveSpeed(base_move_speed);
    }

    public float getBaseScale() {
        return base_scale;
    }

    public float setBaseScale(float base_scale) {
        return this.base_scale = setScale(base_scale);
    }

    public HashMap<Short, Float> getEffectsList() {
        return effectsList;
    }

    public HashMap<Short, Float> setEffectsList(HashMap<Short, Float> effectsList) {
        return this.effectsList = effectsList;
    }

    public void addEffect(short effect_id, float effect_value) {
        effectsList.put(effect_id, effect_value);
    }

    public void removeEffect(short effect_id) {
        effectsList.remove(effect_id);
    }

    public void clearEffectsList() {
        effectsList.clear();
    }

    public Vector<Integer> getTargetList() {
        return targetList;
    }

    public void addTarget(int target_id) {
        targetList.add(target_id);
    }

    public void removeTarget(int target_id) {
        targetList.remove(Integer.valueOf(target_id));
    }

    public void clearTargetList() {
        targetList.clear();
    }

    public int getUserID() {
        return user_id;
    }

    public int setUserID(int user_id) {
        return this.user_id = user_id;
    }
    /*man-
    public GameTimer getHealthRegenTimer() {
        return healthRegenTimer;
    }

    public void startHealthRegenTimer(int delay) {
        healthRegenTimer.schedule(new GameTimerCollection.HealthRegenTimer(this), delay, delay);
    }

    public void stopHealthRegenTimer() {
        if (healthRegenTimer.getTask() != null) {
            healthRegenTimer.getTask().cancel();
        }
    }*/
}
